package ruletree.rule;

import java.util.ArrayList;

import lexicon.Form;
import lexicon.FormList;
import lexicon.Lexicon;
import lexicon.LexiconList;
import managers.LexiconManager;

import org.jdom2.Element;

import components.Children;
import components.Component;
import components.Phrase;
import features.Feature;
import features.FeatureList;

public class Action {
	
	public static final String ATTRIBUTE_NAME = "name";
	public static final String VAR = "var";
	
	private String actionName;
	private String var;
	private Children children; // right
	private FeatureList featureList;
	private FormList formList;
	private Children inputRule; // left
	
	// getters and setters
	public Action(){
	}
	
	public Action(String name){
		this.actionName = name;
	}
	
	public String getActionName() {
		return actionName;
	}
	
	public void setActionName(String actionName) {
		this.actionName = actionName;
	}
	
	public String getVar() {
		return var;
	}
	
	public void setVar(String var) {
		this.var = var;
	}
	
	public FormList getForm() {
		return formList;
	}

	public void setForm(FormList form) {
		this.formList = form;
	}
	
	public Children getChildren() {
		return children;
	}
	
	public void setChildren(Children children) {
		this.children = children;
	}
	
	public FeatureList getFeatureList() {
		return featureList;
	}
	
	public void setFeatureList(FeatureList featureList) {
		this.featureList = featureList;
	}
	
	public FormList getFormList() {
		return formList;
	}
	
	public void setFormList(FormList formList) {
		this.formList = formList;
	}
	
	public Children getInputRule() {
		return inputRule;
	}
	
	public void setInputRule(Children inputRule) {
		this.inputRule = inputRule;
	}
	// predefined method
	
	public void deleteConstituent(String var){
		System.out.println("Delete Constituent");
	}
	
	public void moveConstituent(String var, Children constituent){
		System.out.println("Move constituent");
	}
	
	public void copyConstituent(String var, Children constituent){
		System.out.println("Copy constituent");
	}
	
	public void addConstituent(String var, Children constituent){
		System.out.println("Add Constituent");
	}
	
	public void addFeature(FeatureList features, String var){
		actionName = "addFeature";
		this.var = var;
		featureList = features;
	}
	
	public Component addFeature(Component varAssignments){
		if(varAssignments.getVar().equals(var)){
			ArrayList<Feature> features = featureList.getFeatureList();
			for(Feature feat: features){
				varAssignments.addFeature(feat); // this is not recursive
			}
		} 

		if(varAssignments.getChildren() != null){ // may anak
			ArrayList<Component> children = varAssignments.getChildren().getChildren();
			if(varAssignments.getChildren() != null)
			for(int i=0; i<children.size(); i++){
				varAssignments.getChildren().getChildren().set(i, addFeature(children.get(i)));
			}
		} 
		
		return varAssignments;
	}
	
	public Component changeFeature(Component varAssignments){
		if(varAssignments.getVar().equals(var)){
			ArrayList<Feature> features = featureList.getFeatureList();
			ArrayList<Feature> featureChange = varAssignments.getFeatureList();
			for(int i=0; i<features.size(); i++){ // ipapalit mo
				for(int j=0; j<featureChange.size(); j++){ // kung saan mo papalitan
					if(features.get(i).getName().equalsIgnoreCase(featureChange.get(j).getName())){
						Feature f = featureChange.get(j);
						f.setValue(features.get(i).getValue());
						featureChange.set(j, f);
					}
				}
			}
			
			varAssignments.setFeatureList(new FeatureList(featureChange));
		} 

		if(varAssignments.getChildren() != null){ // may anak
			ArrayList<Component> children = varAssignments.getChildren().getChildren();
			if(varAssignments.getChildren() != null)
			for(int i=0; i<children.size(); i++){
				varAssignments.getChildren().getChildren().set(i, changeFeature(children.get(i)));
			}
		} 
		
		return varAssignments;
	}
	
	
	public Component addConstituent(Component varAssignments){
		if(varAssignments.getVar().equals(var)){
			Component components = Component.createInstance(children.getChildren().get(0).getName(), false);
			if(children.getChildren().get(0).getWord() != null){
				components.setWord(children.getChildren().get(0).getWord());
			}
			if(featureList != null){
				ArrayList<Feature> features = featureList.getFeatureList();

				for(Feature feat: features){
					components.addFeature(feat); // this is not recursive
				}
			}
			varAssignments.getChildren().getChildren().add(components);
		} 

		if(varAssignments.getChildren() != null){ // may anak
			ArrayList<Component> children = varAssignments.getChildren().getChildren();
			if(varAssignments.getChildren() != null)
			for(int i=0; i<children.size(); i++){
				varAssignments.getChildren().getChildren().set(i, addConstituent(children.get(i)));
			}
		} 
		
		return varAssignments;	
	}
	
	public Component orderSubconstituents(Component varAssignments){
		ArrayList<Component> newComponents = new ArrayList<>();
		
		if(varAssignments.getVar().equals(var)){
			ArrayList<Component> oldComponents = varAssignments.getChildren().getChildren();
			String[] order = children.getChildren().get(0).getName().split(" ");
			for(String o : order){
				for(Component c : oldComponents){
					String [] temp = o.split("-");
					if(c.getVar().equals(temp[0]))
						newComponents.add(c);
				}
			}
		}
		


		if(!varAssignments.isLeaf()){
			Phrase phrase = (Phrase) Component.createInstance(varAssignments.getName(), false);
			for(int i=0; i<newComponents.size(); i++){
				phrase.addChild(newComponents.get(i));
			}
			return phrase;

		}
		
		return null;
	}
	
	public Component selectForm(Component varAssignments){
		if(varAssignments.getVar().equals(var)){
			
			LexiconManager lexiconManager = LexiconManager.getInstance();
			LexiconList lexiconList = lexiconManager.getLexiconList(varAssignments.getName().toLowerCase());
			
			ArrayList<Feature> features = varAssignments.getFeatureList();
			ArrayList<Form> forms = formList.getFormList();
		
			
			Feature tempFeature = null;
			
			for(Feature feature : features){
				if(feature.getName().equals("Surface Aspect"))
					tempFeature = feature;
			}
			
			
			if(tempFeature != null)
				for(Lexicon l : lexiconList.getLexiconList()){

					if(l.getName().equalsIgnoreCase(varAssignments.getWord().getRoot())){
						for(Form f : forms){
							varAssignments.getWord().setCurrentForm(l.getFormList().getForm(f.getName()).getValue());
							varAssignments.getWord().setRoot(l.getFormList().getForm(f.getName()).getValue());
						}
					}
					//System.out.println(varAssignments.getWord().getRoot());
					//if(l.getName().equalsIgnoreCase(varAssignments.getWord().getRoot()))
						//varAssignments.getWord().setCurrentForm(l.getFormList().getForm(tempFeature.getValue()).getValue());
				}
			}
		
		if(varAssignments.getChildren() != null){ // may anak
			ArrayList<Component> children = varAssignments.getChildren().getChildren();
			if(varAssignments.getChildren() != null)
			for(int i=0; i<children.size(); i++){
				varAssignments.getChildren().getChildren().set(i, selectForm(children.get(i)));
			}
		} 
		
		return varAssignments;
		
	}
	
	public void deleteFeature(Children constituent){
		System.out.println("Delete feature");
	}
	
	public void addTranslationRoot(Children constituent){
		System.out.println("Added translation");
	}
	
	public void deleteTranslationRoot(Children constituent){
		System.out.println("delete translation");
	}
	
	public void changeTranslationRoot(Children constituent){
		System.out.println("change translation");
	}
	
	public void insertTranslationRoot(Children constituent){
		System.out.println("Added feature");
	}
	
	public void orderSubconstituents(Children constituent){
		System.out.println("order subconstituents");
	}
	
	public String getComponentName(String var){
		String componentName = null;
		
		for(Component c: inputRule.getChildren()){
			if(c.getVar().equalsIgnoreCase(var)){
				componentName = c.getName();
				break;
			}
		}
		return componentName;
	}
	
	//XML generation for action data object
	public Element generateXMLAction(){
		
		Element xmlElement = new Element("action");
		xmlElement.setAttribute(ATTRIBUTE_NAME, actionName);
		xmlElement.setAttribute(VAR, var);
		
		if(children != null){
			for(Component clause: children.getChildren())
				xmlElement.addContent(clause.generateXMLElement());
		}
		
		if(featureList != null){
			Element featuresElement = featureList.generateXMLElementForAction(actionName);
			if(featuresElement != null)
				xmlElement.addContent(featuresElement);
		}
		
		return xmlElement;
				
	}

}
